# -*- coding: utf-8 -*-

import time

from odoo import api, fields, models, _
import odoo.addons.decimal_precision as dp
from odoo.exceptions import UserError


class purchaseprepayPaymentInv(models.TransientModel):
    _name = "purchase.prepay.payment.inv"
    _description = "purchases prepay Payment Invoice"

    @api.model
    def _count(self):
        return len(self._context.get('active_ids', []))

    @api.model
    def _get_prepay_payment_method(self):
        if self._count() == 1:
            purchase_obj = self.env['purchase.order']
            order = purchase_obj.browse(self._context.get('active_ids'))[0]
            if all([line.product_id.invoice_policy == 'order' for line in order.order_line]) or order.invoice_count:
                return 'all'
        return 'delivered'

    # 找到预付款产品,共用销售中的设置
    @api.model
    def _default_product_id(self):
        product_id = self.env['ir.values'].get_default('sale.config.settings', 'deposit_product_id_setting')
        return self.env['product.product'].browse(product_id)

    @api.model
    def _default_deposit_account_id(self):
        return self._default_product_id().property_account_expense_id

    # 获得默认的供应商税
    @api.model
    def _default_deposit_taxes_id(self):
        return self._default_product_id().supplier_taxes_id

    prepay_payment_method = fields.Selection([
        ('delivered', u'可开票的明细行'),
        ('all', u'可开具发票明细 (扣除预付定金)'),
        ('percentage', u'预付定金(百分比)'),
        ('fixed', u'预付定金(固定金额)')
    ], string=u'你要开什么发票？', default=_get_prepay_payment_method, required=True)
    product_id = fields.Many2one('product.product', string=u'付款产品', domain=[('type', '=', 'service')],
                                 default=_default_product_id)
    count = fields.Integer(default=_count, string='# of Orders')
    amount = fields.Float(u'预付定金总额(不含税)', digits=dp.get_precision('Account'),
                          help="The amount to be invoiced in prepay, taxes excluded.")
    deposit_account_id = fields.Many2one("account.account", string=u"费用科目", domain=[('deprecated', '=', False)],
                                         help="Account used for deposits", default=_default_deposit_account_id)
    deposit_taxes_id = fields.Many2many("account.tax", string=u"产品供应商税", help="Taxes used for deposits",
                                        default=_default_deposit_taxes_id)

    @api.onchange('prepay_payment_method')
    def onchange_prepay_payment_method(self):
        if self.prepay_payment_method == 'percentage':
            return {'value': {'amount': 0}}
        return {}

    @api.multi
    def _create_invoice(self, order, po_line, amount):
        inv_obj = self.env['account.invoice']
        ir_property_obj = self.env['ir.property']

        account_id = False
        if self.product_id.id:
            account_id = self.product_id.property_account_expense_id.id
        if not account_id:
            inc_acc = ir_property_obj.get('property_account_expense_categ_id', 'product.category')
            account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False
        if not account_id:
            raise UserError(
                _(
                    'There is no income account defined for this product: "%s". You may have to install a chart of account from Accounting app, settings menu.') %
                (self.product_id.name,))

        if self.amount <= 0.00:
            raise UserError(_('The value of the down payment amount must be positive.'))
        if self.prepay_payment_method == 'percentage':
            amount = order.amount_untaxed * self.amount / 100
            name = _("Down payment of %s%%") % (self.amount,)
        else:
            amount = self.amount
            name = _(u'预付款')
        # 税替代规则
        if order.fiscal_position_id and self.product_id.supplier_taxes_id:
            tax_ids = order.fiscal_position_id.map_tax(self.product_id.supplier_taxes_id).ids
        else:
            tax_ids = self.product_id.supplier_taxes_id.ids

        invoice = inv_obj.create({
            'name': order.name,
            'journal_id': self.env['account.journal'].search([('type', '=', 'purchase')], limit=1).id,
            'origin': order.name,
            'type': 'in_invoice',
            'reference': False,
            'account_id': order.partner_id.property_account_payable_id.id,
            'partner_id': order.partner_id.id,
            'partner_shipping_id': order.partner_id.id,
            'invoice_line_ids': [(0, 0, {
                'name': name,
                'origin': order.name,
                'account_id': account_id,
                'price_unit': amount,
                'quantity': 1.0,
                'discount': 0.0,
                'uom_id': self.product_id.uom_id.id,
                'product_id': self.product_id.id,
                'purchase_line_id': po_line.id,
                'invoice_line_tax_ids': [(6, 0, tax_ids)],
                'account_analytic_id': po_line.account_analytic_id.id or False,
            })],
            'currency_id': order.company_id.currency_id.id,
            'payment_term_id': order.payment_term_id.id,
            'fiscal_position_id': order.fiscal_position_id.id or order.partner_id.property_account_position_id.id,
            # 'team_id': order.team_id.id,
            'comment': order.notes,
        })
        invoice.compute_taxes()
        invoice.message_post_with_view('mail.message_origin_link',
                                       values={'self': invoice, 'origin': order},
                                       subtype_id=self.env.ref('mail.mt_note').id)
        return invoice

    @api.multi
    def create_invoices(self):
        purchase_orders = self.env['purchase.order'].browse(self._context.get('active_ids', []))

        if self.prepay_payment_method == 'delivered':
            invo = purchase_orders.action_invoice_create()
            return invo
        elif self.prepay_payment_method == 'all':
            invo = purchase_orders.action_invoice_create(final=True)
            return invo
        else:
            # Create deposit product if necessary
            if not self.product_id:
                vals = self._prepare_deposit_product()
                self.product_id = self.env['product.product'].create(vals)
                self.env['ir.values'].sudo().set_default('sale.config.settings', 'deposit_product_id_setting',
                                                         self.product_id.id)

            purchase_line_obj = self.env['purchase.order.line']
            for order in purchase_orders:
                if self.prepay_payment_method == 'percentage':
                    amount = order.amount_untaxed * self.amount / 100
                else:
                    amount = self.amount
                if self.product_id.invoice_policy != 'order':
                    raise UserError(_(
                        'The product used to invoice a down payment should have an invoice policy set to "Ordered quantities". Please update your deposit product to be able to create a deposit invoice.'))
                if self.product_id.type != 'service':
                    raise UserError(_(
                        "The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product."))
                if order.fiscal_position_id and self.product_id.supplier_taxes_id:
                    tax_ids = order.fiscal_position_id.map_tax(self.product_id.supplier_taxes_id).ids
                else:
                    tax_ids = self.product_id.supplier_taxes_id.ids
                po_line = purchase_line_obj.create({
                    'name': _(u'预付款:' + ' %s') % (time.strftime('%m %Y'),),
                    'price_unit': amount,
                    'product_qty': 0.0,
                    'date_planned': fields.datetime.now(),
                    'order_id': order.id,
                    'discount': 0.0,
                    'product_uom': self.product_id.uom_id.id,
                    'product_id': self.product_id.id,
                    'taxes_id': [(6, 0, tax_ids)],
                })
                self._create_invoice(order, po_line, amount)
        # if self._context.get('open_invoices', False):
        #     return purchase_orders.action_view_invoice()

        return {'type': 'ir.actions.act_window_close'}

    def _prepare_deposit_product(self):
        return {
            'name': u'预付款',
            'type': 'service',
            'invoice_policy': 'order',
            'property_account_expense_id': self.deposit_account_id.id,
            'taxes_id': [(6, 0, self.deposit_taxes_id.ids)],
        }
